<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    /**
     * Promise 是什么?
     * 用来解决异步编程的新的方案, 从语法上来将, Promise 就是一个构造函数
     * 
     * Promise 作用?
     * 解决回调地狱的问题
     * 
     * let result = '';
     * fs.readFile('./1.html', (err, data) => {
     *    fs.readFile('./2.html', (err, data) => {
     *      fs.readFile('./3.html', (err, data) => {
     *        
     *      })
     *    })
     * })  
     * 
     * Promise 怎么用?
     *  
     * //执行器函数是一个同步回调
     * let p = new Promise((resolve, reject) => {
     *    //主要是异步的任务  定时器, 发送请求, 事件, 文件操作, 数据库操作    异步 IO
     *    setTimeout(() => {
     *      //成功的操作
     *      resolve(); //作用: 改变 promise 实例对象状态为『成功』,并且可以设置promise对象『成功的结果值』
     *      //失败的操作
     *      reject(); //作用: 改变 promise 实例对象状态为『失败』,并且可以设置promise对象『失败的结果值』
     *    }, 1000)
     * });
     * 
     * Promise 状态
     * 『状态』是 promise 实例对象中的一个内部属性, 名字为『PromiseState』
     * 值:  pending, fulfilled, rejected
     * 
     * 变换:
     * pending -> fulfilled
     * pending -> rejected 
     * 
     * 『结果值』是 promise 实例对象中的一个内部属性, 名字为『PromiseResult』
     * 
     * //创建 promise 实例对象的快捷方式
     * Promise.resolve(); //一般是一个成功的 promise 实例对象
     * Promise.reject();  //一定为一个失败的 promise 实例对象
     * Promise.all()
     * Promise.race()
     * 
     * 
     * promise 实例对象结果值的处理
     * * then  用来指定 promise 实例对象成功与失败的回调函数
     * * catch 用来指定 promise 失败的回调函数
     * 
     * 关键问题:
     * 1. 如何修改 promise 实例对象的状态 new Promise()
     *    * resolve
     *    * reject
     *    * throw err;
     * 2. 状态只能修改一次
     * 3. 修改状态与指定回调的先后顺序.  两种情况都有可能
     * 4. then 方法的返回结果
     *    * 是一个 promise 实例对象, 状态由 then 方法所指定的回调函数的执行结果决定
     *    * 若回调函数返回值为 非 promise 的数据, 则 then 返回的 promise 状态就为成功
     *    * 若回调函数返回值为 promise 的数据, 则返回的 promise 对象状态与值就决定了 then 返回的 promise 的状态与值
     *    * 若回调函数执行抛出错误, 则返回的 promise 对象状态为『失败』
     * 5. then 的链式调用
     *    p.then().then().then().catch().then();
     * 6. 异常穿透
     * 7. 中断 promise 链条 
     */

    let p4 = new Promise((resolve, reject) => {
      resolve('ok');
      // reject('error');
    });

    // console.log(p4.then(v => console.log(v)));
    p4.then(v => {
      console.log(v);
      return new Promise(() => {});
    }).then(v => {
      console.log(v);
    }).catch(e => {
      console.log(v);
    })

    //修改状态在前, 指定回调在后
    let p2 = new Promise((resolve, reject) => {
      //直接修改状态
      resolve('ok');
    });

    p2.then(() => {

    });

    //修改状态在后, 指定回调在前
    let p3 = new Promise((resolve, reject) => {
      setTimeout(() => {
        //直接修改状态
        resolve('ok');
      }, 2000)
    });

    p3.then(() => {

    });



    let p = new Promise((resolve, reject) => {
      // resolve('ok');
      reject('error');
    });

    p.then(v => {
      console.log(v);
    }, e => {
      console.log(123);
    }).then(v => {
      console.log(v);
    }).catch(e => {
      console.log(e);
    });

    

  </script>
</body>

</html>